﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace JinJun.YShow.DAL
{
    public class BaseRepository<T, TS> where T : class where TS : DbContext, new()
    {
        //当前操作数据库的实例
        private DbContext db = DbContextFactory<TS>.GetCurrentDbContext();


        /// <summary>
        /// 单表的添加一条记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Add(T entity)
        {
            //将实例添加到上下文中
            db.Set<T>().Add(entity);
            //保存更改
            return db.SaveChanges() > 0;
        }


        /// <summary>
        /// 单表的添加多条记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool AddRange(List<T> entities)
        {
            //将实例添加到上下文中
            db.Set<T>().AddRange(entities);
            //保存更改
            return db.SaveChanges() > 0;
        }



        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Delete(T entity)
        {
            //设置删除状态
            db.Entry(entity).State = EntityState.Deleted;
            //保存更改
            return db.SaveChanges() > 0;
        }


        /// <summary>
        ///删除多个实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool BatchDelete(List<T> entities)
        {
            //批量删除
            db.Set<T>().RemoveRange(entities);
            //保存更改
            return db.SaveChanges() > 0;
        }



        /// <summary>
        ///删除多个实体根据Id
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool BatchDeleteById(params int[] ids)
        {
            foreach (var id in ids)
            {
                //查找主键值的实体
                var entity = db.Set<T>().Find(id);
                if (entity != null)
                {
                    db.Set<T>().Remove(entity);
                }
            }
            //保存更改
            return db.SaveChanges() > 0;
        }



        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Update(T entity)
        {
            //设置修改状态
            db.Entry(entity).State = EntityState.Modified;
            //保存更改
            return db.SaveChanges() > 0;
        }



        /// <summary>
        /// 查询返回一个集合
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public List<T> QueryList(Expression<Func<T, bool>> lambdaExpression)
        {
            return db.Set<T>().Where(lambdaExpression).ToList();
        }


        /// <summary>
        /// 查询返回一个对象,没有返回null---根据主键查
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public T Query(Expression<Func<T, bool>> lambdaExpression)
        {
            return db.Set<T>().SingleOrDefault(lambdaExpression);
        }


        /// <summary>
        ///判断是否存在
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Exists(Expression<Func<T, bool>> lambdaExpression)
        {
            return db.Set<T>().Any(lambdaExpression);
        }



        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public List<T> QueryPageList<S>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderbyLambda, out int count, bool isAsc = true)
        {
            //获取总数
            count = db.Set<T>().Where(whereLambda).Count();
            if (!isAsc)
            {
                return db.Set<T>().Where(whereLambda)
                      .OrderByDescending(orderbyLambda)
                      .Skip((pageIndex - 1) * pageSize)
                      .Take(pageSize).ToList();
            }
            return db.Set<T>().Where(whereLambda)
                  .OrderBy(orderbyLambda)
                  .Skip((pageIndex - 1) * pageSize)
                  .Take(pageSize).ToList();
        }
    }
}
